#pragma once

#include "Common.hpp"
#include "InetAddr.hpp"

class Command 
{
    public:
        // 构造函数
        Command()
        {
            // 插入限定命令
            _WhiteListCommands.insert("ls");
            _WhiteListCommands.insert("pwd");
            _WhiteListCommands.insert("ls -l");
            _WhiteListCommands.insert("touch haha.txt");
            _WhiteListCommands.insert("whoami");
            _WhiteListCommands.insert("who");
        }

        // 判断命令是否在白名单中
        bool IsSafeCommand(const std::string &cmd)
        {
            return _WhiteListCommands.find(cmd)!= _WhiteListCommands.end();
        }

        // 执行函数, 可用于回调
        std::string Execute(const std::string &cmd, InetAddr &addr)
        {
            // 检查命令是否在白名单中
            if(!IsSafeCommand(cmd))
            {
                return "该命令不在白名单中!";
            }

            // 获取发送命令地址信息
            std::string who = addr.StringAddr();

            // 调用popen执行命令
            FILE* fp = popen(cmd.c_str(), "r");
            if(fp ==nullptr)
            {
                return "不存在该命令!";
            }

            // 读取命令执行结果
            char buffer[1024];
            std::string result;
            while(fgets(buffer, sizeof(buffer), fp))
            {
                result += buffer;
            }

            pclose(fp); // 关闭文件流

            return who + "执行命令: " + cmd + " done, result:\n" + result; // 返回命令执行结果
        }

        // 析构函数
        ~Command()
        {}

    private:
        std::set<std::string> _WhiteListCommands; // 白名单命令集合
};